#include "fake.h"
#include "Lock.h"
#include "log.h"

void fake_enclave(void *shared_buffer, notify_normal_func_ptr notify_normal, int pid)
{
    register_um((uint64_t)shared_buffer, UM_SIZE);
    init_um(true);

    bool flag = false;
    int64_t start_time = 0;

    uint8_t tmp_data[4096];
    int64_t total_received = 0;
    int64_t all_received_size = 0;
    while (total_received < NUM_OF_TESTS)
    {
        if (atomic_read_uint32(&has_call))
        {
            while (true)
            {
                op_t op = find_ecall_or_oret();
                if (op.type != UM_CALL)
                {
                    if (op.type != UM_UNUSED)
                    {
                        LOG("ERROR! type=%d\n", op.type);
                        return;
                    }
                    else
                    {
                        break;
                    }
                }
                total_received++;

                if (!flag)
                {
                    start_time = getCurrentMillisecs();
                    flag = true;
                }

                switch (op.func_id)
                {
                case 0:

                    if (total_received % OUTPUT_FREQUENCY == 0)
                    {
                        int64_t end_time = getCurrentMillisecs();
                        int64_t diff = end_time - start_time;
                        TEST_ASSERT_INFO(diff != 0, "diff == 0");
                        LOG("total_call_received=%ld %ld/s op->op_id=%ld, data_size=%d\n", total_received, total_received / diff * 1000, op.op_id, op.param_len);
                    }

                    all_received_size += op.param_len;

                    drop_ebuffer_data();

                    while (async_eret(op.op_id, tmp_data, op.param_len) != 0)
                    {
                        notify_normal(pid);
                    }
                    notify_normal(pid);
                    break;

                default:
                    TEST_PRINT("ERROR! func_id=%d\n", op.func_id);
                    break;
                }
                if (total_received % (int)OUTPUT_FREQUENCY == 0 && total_received)
                {
                    TEST_PRINT("total_received=%ld\n", total_received);
                }
            }
            atomic_write_uint32(&has_call, 0);
            // TEST_PRINT("has_call=false, total_received=%ld\n", total_received);
        }
    }

    TEST_PRINT("get_num_of_ecall_and_oret()=%d\n", get_num_of_ecall_and_oret());
    TEST_ASSERT_INFO(get_num_of_ecall_and_oret() == 0, "get_num_of_ecall_and_oret() != 0");
    TEST_PRINT("exit\n");
}
